package com.cl.code.database.mybatis.module.sql;

import com.cl.code.database.mybatis.module.sql.operator.OrderSqlOperator;
import com.cl.code.database.mybatis.module.sql.table.TableField;
import com.cl.code.database.mybatis.module.sql.table.TableInfo;
import com.cl.code.database.mybatis.module.sql.table.TableInfoFactory;
import lombok.Getter;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author chengliang
 * @since 1.0.0
 */
@Getter
public class Order<Entity> {

    private final Class<Entity> entityClass;

    private final Map<String, OrderSqlOperator> map = new LinkedHashMap<>(5);

    private Order(Class<Entity> entityClass) {
        this.entityClass = entityClass;
    }

    public static <Entity> Order<Entity> of(Class<Entity> tClass) {
        return new Order<>(tClass);
    }

    public Order<Entity> asc(Fn<Entity, Object> column) {
        String name = column.getName();
        map.remove(name);
        map.put(name, OrderSqlOperator.ASC);
        return this;
    }

    public Order<Entity> desc(Fn<Entity, Object> column) {
        String name = column.getName();
        map.remove(name);
        map.put(name, OrderSqlOperator.DESC);
        return this;
    }

    public String getOrderSql() {
        if (map.isEmpty()) {
            return "";
        }

        TableInfo tableInfo = TableInfoFactory.getTableInfo(getEntityClass());
        TableField[] fieldItems = tableInfo.getTableFields();

        Function<String, String> toSnakeCaseFunction = fieldName -> {
            for (TableField item : fieldItems) {
                if (item.getFieldName().equals(fieldName)) {
                    return item.getSqlFieldName();
                }
            }
            return null;
        };

        return map.entrySet().stream()
                .map(entry -> toSnakeCaseFunction.apply(entry.getKey()) + " " + entry.getValue().getOperator())
                .collect(Collectors.joining(","));
    }

}
